package com.zhoug.ocr.textin;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.zhoug.common.content.Optional;
import com.zhoug.common.framework.rxjava2.SchedulerUtils;
import com.zhoug.common.interfaces.DefaultLifecycleObserver;
import com.zhoug.common.utils.JsonUtils;
import com.zhoug.ocr.textin.data.BusinessLicense;
import com.zhoug.ocr.textin.data.FormResult;
import com.zhoug.ocr.textin.data.HeaderField;
import com.zhoug.ocr.textin.data.bill.BaseBill;
import com.zhoug.ocr.textin.data.bill.VatInvoice;
import com.zhoug.ocr.textin.parser.DefaultFormResultParser;
import com.zhoug.ocr.textin.parser.FormResultParser;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.disposables.Disposable;

/**
 * @Author: zhoug
 * @Date: 2023/3/6
 * @Description:
 */
public class TextInOcr {
    private TextInRepository mRepository;
    private LifecycleOwner mLifecycleOwner;
    private List<Disposable> mDisposables;

    public TextInOcr(LifecycleOwner lifecycleOwner) {
        mDisposables = new ArrayList<>();
        mLifecycleOwner = lifecycleOwner;
        mLifecycleOwner.getLifecycle().addObserver(defaultLifecycleObserver);
        mRepository = new TextInRepository();
    }


    public void recognizeBill(String filePath, @NonNull OnOcrResultListener<List<BaseBill>> onOcrResultListener) {
        Disposable subscribe = mRepository.recognizeBill(filePath)
                .observeOn(SchedulerUtils.ui())
                .subscribe(s -> {
                    onOcrResultListener.onSuccess(s.get());
                }, throwable -> {
                    onOcrResultListener.onFailure(throwable.getMessage());
                });
        addDisposable(subscribe);
    }

    /**
     * 增值税发票识别
     *
     * @param filePath            发票路径
     * @param onOcrResultListener 结果回掉
     */
    public void recognizeVatInvoice(String filePath, @NonNull OnOcrResultListener<VatInvoice> onOcrResultListener) {
        Disposable subscribe = mRepository.recognizeVatInvoice(filePath)
                .observeOn(SchedulerUtils.ui())
                .subscribe(s -> {
                    onOcrResultListener.onSuccess(s.get());
                }, throwable -> {
                    onOcrResultListener.onFailure(throwable.getMessage());
                });
        addDisposable(subscribe);
    }

    /**
     * 营业执照识别
     *
     * @param filePath            营业执照图片
     * @param onOcrResultListener 结果回掉
     */
    public void recognizeBusinessLicense(String filePath, @NonNull OnOcrResultListener<BusinessLicense> onOcrResultListener) {
        Disposable subscribe = mRepository.recognizeBusinessLicense(filePath)
                .observeOn(SchedulerUtils.ui())
                .subscribe(s -> {
                    onOcrResultListener.onSuccess(s.get());
                }, throwable -> {
                    onOcrResultListener.onFailure(throwable.getMessage());
                });
        addDisposable(subscribe);
    }

    /**
     * 表格识别
     *
     * @param filePath
     * @param onOcrResultListener
     */
    public void recognizeTable(String filePath, @NonNull OnOcrResultListener<String> onOcrResultListener) {
        Disposable subscribe = mRepository.recognitionForm(filePath)
                .observeOn(SchedulerUtils.ui())
                .subscribe(s -> {
                    onOcrResultListener.onSuccess(JsonUtils.toJson(s.get()));
                }, throwable -> {
                    onOcrResultListener.onFailure(throwable.getMessage());
                });
        addDisposable(subscribe);
    }

    /**
     * 表格识别
     *
     * @param filePath
     * @param headerFields
     * @param parser
     * @param callback
     */
    public void recognizeTable(String filePath, @NonNull List<HeaderField> headerFields, FormResultParser parser, OnOcrResultListener<String> callback) {
        if (parser == null) {
            parser = new DefaultFormResultParser();
        }
        FormResultParser formResultParser = parser;
        Disposable subscribe = mRepository.recognitionForm(filePath)
                .observeOn(SchedulerUtils.io())
                .map(ops -> {
                    FormResult formResult = ops.get();
                    String s = formResultParser.parseFormResult(formResult, headerFields, TextInConfig.getHeaderByOrderPosition());
                    return Optional.create(s);
                })
                .observeOn(SchedulerUtils.ui())
                .subscribe(s -> {
                    callback.onSuccess(s.get());
                }, throwable -> {
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(subscribe);
    }

    private void addDisposable(Disposable disposable) {
        mDisposables.add(disposable);

    }

    private DefaultLifecycleObserver defaultLifecycleObserver = new DefaultLifecycleObserver() {
        @Override
        public void onDestroy(@NonNull LifecycleOwner owner) {
            if (mDisposables != null && mDisposables.size() > 0) {
                for (Disposable item : mDisposables) {
                    item.dispose();
                }
                mDisposables.clear();
            }
        }
    };

}
